﻿//using System;
//using System.Collections.Generic;
//using System.Text;
//using Shprosses.Modelling.Primitives;
//using Shprosses.Calculations;

//namespace Shprosses.Modelling.Components.Constraints
//{
//    /// <summary>
//    /// Ограничение, которое "насаживает" концы примитива компонента на компоненты заданного типа. 
//    /// Под этим понимается само визуальное "одевание", подсчёт углов среза, если, допустим, 
//    /// профиль "насаживается" на коннектор, который расположен под углом к заглушке. При одевании считается, что 
//    /// угол среза берётся у конца IEndedPrimitive.StartPoint.
//    /// Применимо только к компонентам, реализующим IEndedComponent.
//    /// </summary>
//    public class ConnectedComponentsNozzleConstraint : IConstraint
//    {
//        private ConstraintAction action;

//        public ConstraintAction Action
//        {
//            get { return action; }
//        }
//        private bool enabled = true;
//        private Type typeOfConnectedComponent;

//        public ConnectedComponentsNozzleConstraint(Type typeOfConnectedComponent, ConstraintAction action)
//        {
//            this.action = action;
//            this.typeOfConnectedComponent = typeOfConnectedComponent;
//        }

//        #region IConstraint Members

//        public bool Check(IComponent component)
//        {
//            int correctCuts = 0;
//            int connectedComponents = 0;
//            foreach (IComponent connectedComponent in component.ConnectedComponents)
//            {
//                if (!(connectedComponent is IEndedComponent)) continue;
//                if (connectedComponent.GetType() != typeOfConnectedComponent) continue;

//                //IEndedComponent endedComponent = (IEndedComponent)component;
//                //IEndedComponent endedConnectedComponent = (IEndedComponent)connectedComponent;

//                connectedComponents++;
//                IWidePrimitive componentPrimitive = (IWidePrimitive)component.Primitives[0];
//                IWidePrimitive connectedComponentPrimitive = (IWidePrimitive)connectedComponent.Primitives[0];

//                double startPointDistance = ModelCalculations.GetDistance(((IEndedComponent)component).StartPoint, ((IEndedComponent)connectedComponent).StartPoint);
//                double endPointDistance = ModelCalculations.GetDistance(((IEndedComponent)component).EndPoint, ((IEndedComponent)connectedComponent).StartPoint);

//                Line cutLine = new Line(connectedComponentPrimitive.UpBorder.StartPoint, 
//                                        connectedComponentPrimitive.DownBorder.StartPoint);

//                ModelPoint[] newPoints = connectedComponentPrimitive.Intersect(cutLine);

//                if (startPointDistance < endPointDistance)
//                {
//                    if (componentPrimitive.DownBorder.StartPoint.Equals(newPoints[1]) &&
//                       componentPrimitive.UpBorder.StartPoint.Equals(newPoints[2]))
//                        correctCuts++;
//                }
//                else
//                {
//                    if (componentPrimitive.DownBorder.EndPoint.Equals(newPoints[1]) &&
//                        componentPrimitive.UpBorder.EndPoint.Equals(newPoints[2]))
//                        correctCuts++;
//                }
//            }
//            if (correctCuts < connectedComponents)
//                return false;

//            return true;
//        }

//        public void Fix(IComponent component)
//        {
//            if (!enabled) return;

//            foreach (IComponent connectedComponent in component.ConnectedComponents)
//            {
//                if (!(connectedComponent is IEndedComponent)) continue;
//                if (connectedComponent.GetType() != typeOfConnectedComponent) continue;

//                IWidePrimitive componentPrimitive = (IWidePrimitive)component.Primitives[0];
//                IWidePrimitive connectedComponentPrimitive = (IWidePrimitive)connectedComponent.Primitives[0];

//                double startPointDistance = ModelCalculations.GetDistance(((IEndedComponent)component).StartPoint, ((IEndedComponent)connectedComponent).StartPoint);
//                double endPointDistance = ModelCalculations.GetDistance(((IEndedComponent)component).EndPoint, ((IEndedComponent)connectedComponent).StartPoint);

//                Line cutLine = new Line(connectedComponentPrimitive.UpBorder.StartPoint,
//                                        connectedComponentPrimitive.DownBorder.StartPoint);

//                ModelPoint[] newPoints = componentPrimitive.Intersect(cutLine);

//                if (startPointDistance < endPointDistance)
//                {
//                    componentPrimitive.DownBorder.StartPoint = newPoints[1];
//                    componentPrimitive.Update();
//                    componentPrimitive.UpBorder.StartPoint = newPoints[2];
//                    componentPrimitive.Update();
//                }
//                else
//                {
//                    componentPrimitive.DownBorder.EndPoint = newPoints[1];
//                    componentPrimitive.Update();
//                    componentPrimitive.UpBorder.EndPoint = newPoints[2];
//                    componentPrimitive.Update();
//                }
//            }
//        }

//        public bool Enabled
//        {
//            get
//            {
//                return enabled;
//            }
//            set
//            {
//                enabled = value;
//            }
//        }

//        #endregion

//        #region IConstraint Members


//        
//        {
//            get { throw new NotImplementedException(); }
//        }

//        #endregion
//    }
//}
